package com.example.service;

import com.example.domain.Clazz;
import com.example.domain.Schedule;
import com.example.domain.Score;
import com.example.domain.Student;
import com.example.repository.ScoreRepository;
import com.example.util.EasyuiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ScoreService {
    
    @Autowired
    private ScoreRepository scoreRepository;
    
    @Autowired
    private ScheduleService scheduleService;
    
    
    @Transactional
    public EasyuiResult<Score> list(final int page, final int rows, final String sortColumn, final String order,
                                    final int clazzid, final int courseid) {
        
        log.info("成绩列表,参数为 page={},row={},sortColumn={},order={},clazzid={},courseid={}",
                page, rows, sortColumn, order, clazzid, courseid);
        
        
        Sort sort = new Sort(Sort.Direction.fromString(order), sortColumn);
        final PageRequest pageRequest = PageRequest.of(page, rows, sort);
        Page<Score> all = null;
        
        if (clazzid > 0 && courseid > 0) {
            final List<Schedule> list = scheduleService.list(clazzid, courseid);
            final Set<Clazz> collect = list.stream().map(Schedule::getClazz).collect(Collectors.toSet());
            if (collect.size() > 1) {
                log.debug("课程表信息有误,该班级(clazzid={})存在多门相同的课程(courseid={})", clazzid, courseid);
                return null;
            } else if (collect.size() == 0) {
                log.debug("该班级(clazzid={})没有学习这门科目(courseid={})", clazzid, courseid);
                return null;
            }
            // 根据clazzid和courseid查询出来的课程,也就是某班某科目的课程表,已经判断是否合法,此处必有值
            final Schedule schedule = list.get(0);
            final int id = schedule.getId();
            
            //根据课程查询出该课程所对应的学生列表
            final List<Student> studentList = schedule.getClazz().getStudentList();
            
            //在成绩表中已经存在的成绩信息,有可能不完全.
            final List<Score> existStudentInScore = scoreRepository.findAllByScheduleForList(id);
            
            //取出成绩表中已经有成绩的学生列表
            final Set<Score> collect1 = existStudentInScore.stream().map(e -> {
                final Student student = e.getStudent();
                studentList.remove(student);
                return e;
            }).collect(Collectors.toSet());
            final Set<Score> notExistScore = studentList.stream().map(s -> {
                Score score = new Score();
                score.setNum(0);
                score.setStudent(s);
                score.setSchedule(schedule);
                return score;
            }).collect(Collectors.toSet());
            collect1.addAll(notExistScore);
            scoreRepository.saveAll(collect1);
            all = scoreRepository.findAllBySchedule(id, pageRequest);
        } else {
            all = scoreRepository.findAll(pageRequest);
        }
        all.stream().forEach(System.out::println);
        
        final List<Score> scoresList = all.getContent();
        
        EasyuiResult<Score> result = new EasyuiResult<>();
        result.setRows(scoresList);
        result.setTotal(all.getTotalElements());
        return result;
    }
    
    /**
     * 根据studentid列表删除成绩信息
     *
     * @param studentids studentids
     */
    @Transactional
    public void deleteByStudentId(final int[] studentids) {
        List<Integer> list = new ArrayList<>();
        for (final int id : studentids) {
            list.add(id);
        }
        scoreRepository.deleteByStudent_Id(list);
    }
    
    /**
     * 根据schedule ids删除score数据
     *
     * @param scheduleids 课程ids
     */
    @Transactional
    public void deleteByScheduleId(final Iterable<Integer> scheduleids) {
        log.debug("ScheduleService.deleteByScheduleId scheduleids={}", scheduleids);
        scoreRepository.deleteBySchedule_IdIn(scheduleids);
    }
    
    
    /**
     * 按照clazzid删除score
     * 先将clazzid对应schedule查出来,再讲schedule对应的score删除.
     *
     * @param clazzids 班级id列表
     */
    @Transactional
    public void deleteByClazzId(Iterable<Integer> clazzids) {
        final Iterable<Schedule> schedules = scheduleService.findAllByClazzId(clazzids);
        List<Integer> list = new ArrayList<>();
        schedules.forEach(s -> {
            list.add(s.getId());
        });
        this.deleteByScheduleId(list);
        
    }
    
    /**
     * 根据课程(scheduleids)查询出所有的成绩
     *
     * @param scheduleids 课程ids
     * @return 成绩列表
     */
    public Iterable<Score> findAllByScheduleId(Iterable<Integer> scheduleids) {
        return scoreRepository.findAllBySchedule_id(scheduleids);
    }
    
}
